package com.itany.nmms.service.impl;

import com.itany.mvc.util.CommonsMultipartFile;
import com.itany.nmms.constant.DictConstant;
import com.itany.nmms.dao.ProductMapper;
import com.itany.nmms.dao.SequenceMapper;
import com.itany.nmms.entity.Product;
import com.itany.nmms.entity.ProductExample;
import com.itany.nmms.entity.Sequence;
import com.itany.nmms.entity.SequenceExample;
import com.itany.nmms.exception.FileUploadErrorException;
import com.itany.nmms.exception.ProductExistException;
import com.itany.nmms.exception.RequestParameterErrorException;
import com.itany.nmms.factory.ObjectFactory;
import com.itany.nmms.service.ProductService;
import com.itany.nmms.util.ParameterUtil;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author 石小俊
 * @date 2023年11月10日 10:35
 */
public class ProductServiceImpl implements ProductService {
    @Override
    public void addProduct(String name, String price, List<CommonsMultipartFile> files, String typeId, HttpSession session) throws RequestParameterErrorException, ProductExistException, FileUploadErrorException {
        ProductMapper productMapper = (ProductMapper) ObjectFactory.getObject("productMapper");
        SequenceMapper sequenceMapper = (SequenceMapper) ObjectFactory.getObject("sequenceMapper");
        if (ParameterUtil.isNull(name) || ParameterUtil.isNull(price) || files.isEmpty() || ParameterUtil.isNull(typeId)) {
            throw new RequestParameterErrorException("请求参数有误");
        }

        // 添加商品时只有一张图片,取出这一张图片
        CommonsMultipartFile file = files.get(0);
        if (file.isEmpty()) {
            throw new RequestParameterErrorException("商品图片不能为空");
        }

        // 判重校验,同一种类型的商品名称不能重复
        ProductExample example = new ProductExample();
        example.or()
                .andProductTypeIdEqualTo(Integer.parseInt(typeId))  // 类型相同
                .andNameEqualTo(name);  // 名称相同
        List<Product> products = productMapper.selectByExample(example);
        if (!products.isEmpty()) {
            throw new ProductExistException("该商品已经存在");
        }

        // 准备一个商品对象,用于实现添加功能
        Product product = new Product();
        product.setName(name);
        product.setPrice(Double.parseDouble(price));
        product.setProductTypeId(Integer.parseInt(typeId));

        // 生成商品编号
        // 编号由三部分组成:前缀、日期、序列号
        // 可以根据前缀去序列号表中进行查询,根据查询结果分为两种场景
        SequenceExample sequenceExample = new SequenceExample();
        sequenceExample.or()
                .andNameEqualTo(DictConstant.PRODUCT_NO_PREFIX);
        List<Sequence> sequences = sequenceMapper.selectByExample(sequenceExample);
        // 1.如果没有查询到数据,则说明尚未使用过对应序列号
        if (sequences.isEmpty()) {
            // 创建一个初始序列号数据
            Sequence sequence = new Sequence();
            sequence.setName(DictConstant.PRODUCT_NO_PREFIX);
            sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);

            // 执行添加操作,将当前序列号的数据添加到数据库中
            sequenceMapper.insertSelective(sequence);

            // 生成此时对应的商品编号
            product.setProductNo(DictConstant.PRODUCT_NO_PREFIX + new SimpleDateFormat("yyyyMMdd").format(new Date()) + sequence.getValue());
        } else {
            // 2.数据库中已经存在对应序列号
            // 此时的查询结果中一定有且仅有一条数据
            // 取出这一条数据
            Sequence sequence = sequences.get(0);
            // 判断当前序列号的值是否达到了最大值
            if (DictConstant.PRODUCT_NO_SEQUENCE_MAX_VALUE.equals(sequence.getValue())) {
                // 如果达到了最大值,则下一个值为初始值
                sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);
            } else {
                // 如果没有达到最大值,则下一个值在原有值的基础上+1,且保持格式不变
                sequence.setValue(ParameterUtil.nextSequence(sequence.getValue()));
            }

            // 执行修改操作
            sequenceMapper.updateByPrimaryKeySelective(sequence);
            // 生成此时对应的商品编号
            product.setProductNo(DictConstant.PRODUCT_NO_PREFIX + new SimpleDateFormat("yyyyMMdd").format(new Date()) + sequence.getValue());
        }

        // 上传商品图片
        // 在服务器创建一个用于存放所有图片的根目录
        // 且在根目录中根据日期创建对应子目录
        String path = DictConstant.PRODUCT_IMAGE_ROOT_DIRECTORY + new SimpleDateFormat("yyyyMMdd").format(new Date());
        // 获取绝对路径
        String cp = session.getServletContext().getRealPath(path);
        File f = new File(cp);
        f.mkdirs();

        // 为了防止出现图片重名,为图片重名,添加一个日期毫秒数的后缀
        String fileName = file.getOriginalFilename();
        fileName = fileName.substring(0, fileName.lastIndexOf(".")) + "-" + new Date().getTime() + fileName.substring(fileName.lastIndexOf("."));

        // 设置存储到数据库中商品图片的值
        product.setImage(path + "/" + fileName);

        // 添加商品
        productMapper.insertSelective(product);
        try {
            // 上传图片
            file.transferTo(new File(cp, fileName));
        } catch (Exception e) {
            e.printStackTrace();
            throw new FileUploadErrorException("商品图片上传失败");
        }


    }
}
